home *** CD-ROM | disk | FTP | other *** search
Text File | 1987-07-06 | 55.6 KB | 2,033 lines |
- Path: uunet!rs
- From: rs@uunet.UU.NET (Rich Salz)
- Newsgroups: comp.sources.unix
- Subject: v10i040: Interpreted Functional Programming lanuage, Part 07/07
- Message-ID: <580@uunet.UU.NET>
- Date: 7 Jul 87 23:23:10 GMT
- Organization: UUNET Communications Services, Arlington, VA
- Lines: 2022
- Approved: rs@uunet.uu.net
-
- Mod.sources: Volume 10, Number 40
- Submitted by: robison@b.cs.uiuc.edu (Arch Robison)
- Archive-name: ifp/Part07
-
- #! /bin/sh
- # This is a shell archive, meaning:
- # 1. Remove everything above the #! /bin/sh line.
- # 2. Save the resulting text in a file.
- # 3. Execute the file with /bin/sh.
- # The following files will be created:
- # interp/outfun.c
- # interp/outob.c
- # interp/stats.c
- # interp/stats.h
- # interp/string.c
- # interp/string.h
- # interp/struct.h
- # interp/trace.c
- # interp/umax.h
- # interp/xdef.c
- export PATH; PATH=/bin:$PATH
- mkdir interp
- if test -f 'interp/outfun.c'
- then
- echo shar: over-writing existing file "'interp/outfun.c'"
- fi
- cat << \SHAR_EOF > 'interp/outfun.c'
-
- /****** outfun.c ******************************************************/
- /** **/
- /** University of Illinois **/
- /** **/
- /** Department of Computer Science **/
- /** **/
- /** Tool: IFP Version: 0.5 **/
- /** **/
- /** Author: Arch D. Robison Date: June 30, 1985 **/
- /** **/
- /** Revised by: Arch D. Robison Date: Dec 12, 1985 **/
- /** **/
- /** Principal Investigators: Prof. R. H. Campbell **/
- /** Prof. W. J. Kubitz **/
- /** **/
- /** **/
- /**------------------------------------------------------------------**/
- /** (C) Copyright 1987 University of Illinois Board of Trustees **/
- /** All Rights Reserved. **/
- /**********************************************************************/
-
-
- #include <stdio.h>
- #include <ctype.h>
- #include "struct.h"
- #include "node.h"
-
- /*
- * OutLongNode - internal to OutNode
- */
- void OutLongNode (N)
- register NodePtr N;
- {
- if (N->NodeParent != NULL) {
- OutLongNode (N->NodeParent);
- printf ("/");
- OutString (N->NodeName);
- }
- }
-
- /*
- * OutNode
- *
- * Output a node in UNIX path format.
- * Abbreviate if it is in the current directory.
- */
- void OutNode (N)
- register NodePtr N;
- {
- register NodePtr M;
- extern boolean LongPathFlag;
-
- if (N == NULL) printf ("(NULL NODE)");
- else {
- if (!LongPathFlag && NULL != (M = FindNode (CurWorkDir,N->NodeName)) &&
- (M->NodeType == IMPORT || M->NodeType == DEF))
- OutString (N->NodeName);
- else OutLongNode (N);
- }
- }
-
- /*
- * OutForm
- *
- * Print a functional form and its parameters.
- *
- * Input
- * N = pointer to form node
- * P = pointer to parameter list
- * Depth = depth to print function (ellipses used at that depth)
- */
- void OutForm (N,P,Depth)
- register NodePtr N;
- ListPtr P;
- int Depth;
- {
- long L;
- register FormEntry *T;
-
- L = ListLength (P);
-
- for (T=FormTable; T<ArrayEnd(FormTable); T++)
- if (T->FormNode == N) {
- switch (T-FormTable) {
-
- case NODE_Comp:
- while (P!=NULL) {
- OutFun (&P->Val,Depth);
- if (NULL != (P=P->Next)) printf ("|");
- }
- break;
-
- case NODE_Cons:
- printf ("[");
- while (P!=NULL) {
- OutFun (&P->Val,Depth);
- if (NULL != (P=P->Next)) printf (",");
- }
- printf ("]");
- break;
-
- case NODE_RInsert:
- case NODE_Filter:
- case NODE_Each:
- printf ("%s ",T->FormInPrefix);
- OutFun (&P->Val,Depth);
- printf (" END");
- break;
-
- case NODE_If:
- printf ("IF "); OutFun (&P->Val,Depth);
- printf (" THEN "); OutFun (&(P=P->Next)->Val,Depth);
- printf (" ELSE "); OutFun (&P->Next->Val,Depth);
- printf (" END");
- break;
-
- case NODE_C:
- if (!L) {
- printf ("?");
- break;
- }
- /* else drop through */
- #if FETCH
- case NODE_Fetch:
- #endif
- case NODE_Out:
- printf ("%s",T->FormInPrefix); OutObject (&P->Val);
- break;
-
- case NODE_Sel:
- if (P->Val.Int >= 0) printf ("%d",P->Val.Int);
- else printf ("%dr",-P->Val.Int);
- break;
-
- case NODE_While:
- printf ("WHILE "); OutFun (&P->Val,Depth);
- printf (" DO "); OutFun (&P->Next->Val,Depth);
- printf (" END");
- break;
- #if XDEF
- case NODE_XDef: {
- extern void OutLHS ();
- printf ("{"); OutLHS (&P->Val);
- printf (" := "); OutFun (&P->Next->Val,Depth);
- printf ("} ");
- OutFun (&P->Next->Next->Val,Depth);
- break;
- }
- #endif
- }
- return;
- }
-
- printf ("(");
- OutNode (N);
- for (; P != NULL; P=P->Next) {
- printf (" ");
- OutObject (&P->Val);
- }
- printf (")");
- }
-
-
- /*
- * OutFun
- *
- * Print function *F. *F may be linked if it was unlinked.
- *
- * The possible representations for the function are described
- * in the comments for "Apply" in apply.c.
- *
- * Input
- * *F = function
- * Depth = depth to print function, 0 = "..."
- *
- * Output
- * *F = may be linked function
- */
- void OutFun (F,Depth)
- register ObjectPtr F;
- int Depth;
- {
- register ListPtr P;
-
- if (SysStop > 1) return;
-
- if (F == NULL) printf ("(null)"); /* Internal error */
- else if (--Depth < 0) printf ("..");
- else
-
- switch (F->Tag) {
-
- default:
- printf ("(tag = %d)",F->Tag); /* Internal error */
- break;
-
- case LIST:
- P = F->List;
- if (P == NULL) printf ("()");
- else
-
- switch (P->Val.Tag) {
-
- case LIST: /* unlinked form */
- LinkPath (&P->Val,DEF);
- if (P->Val.Tag!=NODE||P->Val.Node->NodeType!=DEF) {
- printf ("(");
- OutObject (&P->Val);
- for (; P != NULL; P=P->Next) {
- printf (" ");
- OutObject (&P->Val);
- }
- printf (")");
- return;
- } /* else drop down to case NODE */
-
- case NODE: /* linked form */
- OutForm (P->Val.Node,P->Next,Depth);
- return;
-
- case STRING:
- LinkPath (F,DEF);
- if (F->Tag == NODE) break; /* drop down to case NODE */
-
- default: /* unlinked function or internal error */
- for (; P!=NULL; P=P->Next) {
- printf ("/");
- OutObject (&P->Val);
- }
- return;
- }
-
- case NODE:
- OutNode (F->Node);
- break;
-
- case STRING:
- OutString (F->String);
- break;
- }
- }
-
-
- /******************************* end of outfun.c ******************************/
-
- SHAR_EOF
- if test -f 'interp/outob.c'
- then
- echo shar: over-writing existing file "'interp/outob.c'"
- fi
- cat << \SHAR_EOF > 'interp/outob.c'
-
- /****** out.c *********************************************************/
- /** **/
- /** University of Illinois **/
- /** **/
- /** Department of Computer Science **/
- /** **/
- /** Tool: IFP Version: 0.5 **/
- /** **/
- /** Author: Arch D. Robison Date: May 1, 1985 **/
- /** **/
- /** Revised by: Arch D. Robison Date: Feb 8, 1987 **/
- /** **/
- /** Principal Investigators: Prof. R. H. Campbell **/
- /** Prof. W. J. Kubitz **/
- /** **/
- /** **/
- /**------------------------------------------------------------------**/
- /** (C) Copyright 1987 University of Illinois Board of Trustees **/
- /** All Rights Reserved. **/
- /**********************************************************************/
-
-
- #include <stdio.h>
- #include <ctype.h>
- #include "struct.h"
- #include "string.h"
-
- #define BerkMode 0
-
- #define INDENT 3
-
- /*
- * OutIndent
- *
- * Indent N places
- */
- void OutIndent (N)
- int N;
- {
- for (; N >= 8; N-=8) printf ("\t");
- while (--N >=0) printf (" ");
- }
-
- /*
- * QuoteCheck
- *
- * Check if string should be quoted.
- *
- * Input
- * S = string
- * Output
- * result = quote character ('\0','\'', or '\"');
- */
- char QuoteCheck (S)
- StrPtr S;
- {
- CharPtr U;
- char Buf[256];
- boolean Single=0,Double=0,Quote=0;
- register char *T;
-
- if (S==NULL) return ('\"');
- else {
- CPInit (&U,&S);
- if (CPRead (&U,Buf,sizeof (Buf))) {
- if (Buf [1] == '\0' && (Buf[0]=='f' || Buf[0]=='t' || Buf[0]=='?'))
- return '\"';
- do
- for (T = Buf; *T; T++)
- if (!isalpha (*T)) {
- Quote=1;
- if (*T == '\'') Single = 1;
- if (*T == '\"') Double = 1;
- }
- while (CPRead (&U,Buf,sizeof (Buf)));
- }
-
- if (!Quote) return '\0';
- else if (Single) return '\"';
- else if (Double) return '\'';
- else return '\"'; /* Should be something else */
- }
- }
-
- /*
- * OutString
- *
- * Output a string.
- */
- void OutString (S)
- StrPtr S;
- {
- char Buf[256];
- CharPtr U;
-
- if ((Debug & DebugRef) && S != NULL) printf ("[%d]",S->SRef);
- CPInit (&U,&S);
- while (CPRead (&U,Buf,sizeof (Buf))) printf ("%s",Buf);
- }
-
- /*
- * OutList
- *
- * Input
- * P = list to output
- */
- void OutList (P)
- register ListPtr P;
- {
- printf ("<");
- if (P!=NIL)
- while (1) {
- if (Debug & DebugRef) printf ("{%d}",P->LRef + (1 - LRefOne));
- OutObject (& P->Val);
- if ((P=P->Next) == NULL) break;
- else printf (",");
- }
- printf (">");
- }
-
-
- /*
- * OutObject
- *
- * Output an object
- *
- * No reference counts change.
- */
- void OutObject (X)
- ObjectPtr X;
- {
- if (SysStop > 1) return;
- else if (X == NULL) printf ("(NULL)");
- else
- switch (X->Tag) {
- case BOTTOM: printf ("?"); break;
- case BOOLEAN:
- switch (X->Bool) {
- case 0: printf (BerkMode ? "F" : "f"); break;
- case 1: printf (BerkMode ? "T" : "t"); break;
- default: printf ("(BOOLEAN %d)",X->Bool); break;
- }
- break;
- case INT:
- printf ("%ld",X->Int);
- break;
-
- case FLOAT:
- printf ("%g",X->Float);
- break;
-
- case LIST:
- OutList (X->List);
- break;
-
- case STRING: {
- register char Q;
- Q = QuoteCheck (X->String);
- if (Q) printf ("%c",Q);
- OutString (X->String);
- if (Q) printf ("%c",Q);
- } break;
-
- case NODE:
- OutNode (X->Node);
- break;
- default:
- printf ("(tag = %d)",X->Tag);
- break;
- }
- }
-
- #define LineLength 80
-
- /*
- * OutLength
- *
- * Compute approximate number of characters required to output an object.
- * The count is stopped prematurely if it goes over LineLength.
- *
- * No reference counts change.
- */
- private int OutLength (X,Limit)
- ObjectPtr X;
- int Limit;
- {
- register ListPtr P;
- register int K;
-
- if (X == NULL) K = 6; /* "(null)" */
- else
- switch (X->Tag) {
-
- case BOTTOM:
- case BOOLEAN:
- K = 1; /* "?","t","f" */
- break;
-
- case INT:
- K = 5;
- break;
-
- case FLOAT:
- K = 8;
- break;
-
- case LIST:
- K = 2; /* <> */
- for (P=X->List; P!=NULL && K <= Limit; P=P->Next)
- K += 1 + OutLength (&P->Val,Limit); /* 1 for space between */
- break;
-
- case STRING:
- K = 2 + LenStr (X->String); /* "'...'" */
- break;
- default:
- K=0;
- break;
- }
- return K;
- }
-
- /*
- * OutPretty
- *
- * Output an object with indented sublists
- *
- * No reference counts change.
- */
- void OutPretty (X,Indent)
- ObjectPtr X;
- int Indent;
- {
- register ListPtr P;
-
- if (SysStop > 1) return;
- OutIndent (Indent);
- if (X == NULL) printf ("(null)");
- else if (X->Tag != LIST) OutObject (X);
- else {
- if ((OutLength (X,LineLength) + Indent) > LineLength) {
- printf ("<\n");
- for (P = X->List; P!=NULL; P=P->Next)
- OutPretty (&P->Val,Indent+INDENT);
- OutIndent (Indent);
- printf (">\n");
- return;
- } else OutList (X->List);
- }
- printf ("\n");
- }
-
-
- /************************** end of outob.c **************************/
-
- SHAR_EOF
- if test -f 'interp/stats.c'
- then
- echo shar: over-writing existing file "'interp/stats.c'"
- fi
- cat << \SHAR_EOF > 'interp/stats.c'
-
- /****** stats.c *******************************************************/
- /** **/
- /** University of Illinois **/
- /** **/
- /** Department of Computer Science **/
- /** **/
- /** Tool: IFP Version: 0.5 **/
- /** **/
- /** Author: Arch D. Robison Date: May 1, 1985 **/
- /** **/
- /** Revised by: Arch D. Robison Date: Dec 8, 1985 **/
- /** **/
- /** Principal Investigators: Prof. R. H. Campbell **/
- /** Prof. W. J. Kubitz **/
- /** **/
- /** **/
- /**------------------------------------------------------------------**/
- /** (C) Copyright 1987 University of Illinois Board of Trustees **/
- /** All Rights Reserved. **/
- /**********************************************************************/
-
- /* Statistics collection routines */
-
- #include "struct.h"
- #include "stats.h"
- #include <stdio.h>
-
- #if STATS
-
- long StatRecycle=0,StatFresh=0;
- long StatArg [MAXTAG+1];
- long Stat_Apply [StatLimLen+1];
- long Stat_NewList [StatLimLen+1];
- long Stat_DelLPtrIn [StatLimLen+1];
- long Stat_DelLPtrOut [StatLimLen+1];
- long Stat_Construct [StatLimLen+1];
- long Stat1Simple,Stat2Simple;
- long StatC = 0;
-
- void StatConstant (InOut)
- ObjectPtr InOut;
- {
- StatC++;
- }
-
- void StatConstruct (P)
- ListPtr P;
- {
- register int N;
- N = ListLength (P);
- if (N >= StatLimLen) N = StatLimLen;
- ++Stat_Construct[N];
- }
-
- void StatNewList (N)
- long N;
- {
- StatFresh += N;
- if (N > StatLimLen) N = StatLimLen;
- ++Stat_NewList [N];
- }
-
- void StatDelLPtr (P)
- register ListPtr P;
- {
- register int N;
-
- N = ListLength (P);
- if (N >= StatLimLen) N = StatLimLen;
-
- ++Stat_DelLPtrIn [N];
- for (N=0; P!=NULL; P=P->Next)
- if (P->LRef > LRefOne || ++N >= StatLimLen) break;
- ++Stat_DelLPtrOut [N];
- }
-
- #define SCALAR ((1<<INT)|(1<<FLOAT)|(1<<BOOLEAN)|(1<<STRING))
-
- void StatApply (InOut)
- ObjectPtr InOut;
- {
- ListPtr P;
- long L;
-
- StatArg [InOut->Tag] ++;
- if (InOut->Tag == LIST) {
- L = ListLength (InOut->List);
- if (L > StatLimLen) L = StatLimLen;
- Stat_Apply [L] ++;
- if (L == 2) {
- P = InOut->List;
- if ((1<<P->Val.Tag) & SCALAR) Stat1Simple++;
- if ((1<<P->Next->Val.Tag) & SCALAR) Stat2Simple++;
- }
- }
- }
-
-
- /*
- * ShowDist
- */
- void ShowDist (Title,Dist)
- char *Title;
- long Dist[];
- {
- int k;
- long S,Z;
-
- for (S=0, k=0; k<=StatLimLen; k++) S += Dist[k];
-
- printf (" %s (total = %ld)\n ",Title,S);
- if (S)
- for (k=0; k<=StatLimLen; k++) {
- Z = 1000 * Dist[k]/S;
- printf ("%ld.%ld%% [%s%ld] ",Z/10,Z%10,k==StatLimLen?">=":"",k);
- Dist[k] = 0;
- }
- printf ("\n");
- }
-
- /*
- * ShowStats
- */
- void ShowStats ()
- {
- long Total;
- int k;
-
- printf ("\n");
- Total = StatRecycle + StatFresh;
- printf ("Memory management\n");
- printf (" Total cells created = %ld\n",Total);
- printf (" Percent of cells recycled = %ld\n",
- Total ? 100*StatRecycle/Total : 0L);
- ShowDist ("New list length distribution",Stat_NewList);
- StatRecycle = StatFresh = 0;
- ShowDist ("Deleted list (total) length distribution",Stat_DelLPtrIn);
- ShowDist ("Deleted list (partial) length distribution",Stat_DelLPtrOut);
- ShowDist ("Constructor list length distribution",Stat_Construct);
- printf ("\n");
-
- printf ("Constant function applications = %d\n",StatC);
- StatC = 0;
- printf ("\n");
-
- if (Stat_Apply [2]) {
- Stat1Simple = 100 * Stat1Simple / Stat_Apply [2];
- Stat2Simple = 100 * Stat2Simple / Stat_Apply [2];
- }
- if (StatArg[LIST])
- for (k=0; k<=StatLimLen; k++)
- Stat_Apply [k] = 100 * Stat_Apply [k] / StatArg[LIST];
- Total = 0;
- for (k=0; k<=MAXTAG; k++) Total += StatArg [k];
- if (Total)
- for (k=0; k<=MAXTAG; k++) StatArg [k] = 100 * StatArg [k] / Total;
- printf ("\n");
- printf ("Apply arguments (Total = %ld)\n",Total);
- printf (" Boolean = %ld, Int = %ld, Float = %ld, String = %ld\n",
- StatArg[BOOLEAN],StatArg[INT],StatArg[FLOAT],StatArg[STRING]);
- printf (" List = %ld\n",StatArg[LIST]);
- printf (" ");
- for (k=0; k<StatLimLen; k++) printf ("%ld [%ld], ",Stat_Apply [k],k);
- printf ("%ld [>=%d]\n",Stat_Apply [StatLimLen],StatLimLen);
- printf (" Pair elements [scalar]<%ld,%ld>\n",Stat1Simple,Stat2Simple);
- Stat1Simple = Stat2Simple = 0;
- for (k=0; k<=StatLimLen; k++) Stat_NewList [k] = Stat_Apply[k] = 0;
- for (k=0; k<=MAXTAG; k++) StatArg[k] = 0;
- }
- #endif
-
- /**************************** end of stats.c ****************************/
-
- SHAR_EOF
- if test -f 'interp/stats.h'
- then
- echo shar: over-writing existing file "'interp/stats.h'"
- fi
- cat << \SHAR_EOF > 'interp/stats.h'
-
- /****** stats.h *******************************************************/
- /** **/
- /** University of Illinois **/
- /** **/
- /** Department of Computer Science **/
- /** **/
- /** Tool: IFP Version: 0.5 **/
- /** **/
- /** Author: Arch D. Robison Date: May 1, 1985 **/
- /** **/
- /** Revised by: Arch D. Robison Date: Dec 8, 1985 **/
- /** **/
- /** Principal Investigators: Prof. R. H. Campbell **/
- /** Prof. W. J. Kubitz **/
- /** **/
- /** **/
- /**------------------------------------------------------------------**/
- /** (C) Copyright 1987 University of Illinois Board of Trustees **/
- /** All Rights Reserved. **/
- /**********************************************************************/
-
- /*
- * Defining STATS=1 causes interpreter to collect statistics.
- * Define STATS=0 for production work since statistics collection
- * slows the interpreter.
- */
- #define STATS 0
-
- #if STATS
-
- #define StatLimLen 5
- #define Stat(X) X
- extern long StatRecycle,StatFresh;
- extern long StatArg [];
- extern long Stat_Apply [];
- extern long Stat_NewList [];
- extern long Stat1Simple,Stat2Simple;
- extern void ShowStats();
- extern void StatApply(), StatConstruct(), StatConstant();
- extern void StatNewList(), StatDelLPtr();
- #else
-
- #define Stat(X)
-
- #endif
-
- /**************************** end of stats.h ****************************/
-
- SHAR_EOF
- if test -f 'interp/string.c'
- then
- echo shar: over-writing existing file "'interp/string.c'"
- fi
- cat << \SHAR_EOF > 'interp/string.c'
-
- /****** string.c ******************************************************/
- /** **/
- /** University of Illinois **/
- /** **/
- /** Department of Computer Science **/
- /** **/
- /** Tool: IFP Version: 0.5 **/
- /** **/
- /** Author: Arch D. Robison Date: May 1, 1985 **/
- /** **/
- /** Revised by: Arch D. Robison Date: Jan 20, 1987 **/
- /** **/
- /** Principal Investigators: Prof. R. H. Campbell **/
- /** Prof. W. J. Kubitz **/
- /** **/
- /** **/
- /**------------------------------------------------------------------**/
- /** (C) Copyright 1987 University of Illinois Board of Trustees **/
- /** All Rights Reserved. **/
- /**********************************************************************/
-
- #include <stdio.h>
- #include "struct.h"
- #include "node.h"
- #include "umax.h"
- #include "string.h"
-
- /* Single character strings, CharString [0] = null string */
- StrPtr *CharString;
-
- /* Free string segments have SRef = 1 and are linked by StrNext link */
- StrPtr FreeString = NULL;
-
- /*
- * NewSCell
- *
- * return pointer to fresh string cell with SRef = 1 and StrNext = NULL.
- *
- * A SysError may occur, in which case the NULL pointer is returned.
- */
- private StrPtr NewSCell ()
- {
- extern StrPtr AllocStrPage ();
- register StrPtr S;
-
- semaphore_wait (SRefSemaphore);
- if (FreeString != NULL || (FreeString = AllocStrPage ()) != NULL) {
- S = FreeString;
- FreeString = S->StrNext;
- S->SRef = 1;
- S->StrNext = NULL;
- }
- else {
- SysError = NO_STR_FREE;
- printf ("NO MORE STRING CELLS LEFT\n");
- S = NULL;
- }
- semaphore_signal (SRefSemaphore);
- return S;
- }
-
- /*
- * CPInit
- *
- * Initialize a character pointer.
- */
- void CPInit (U,S)
- register CharPtr *U;
- register StrPtr *S;
- {
- if ((U->CPSeg = *(U->CPStr = S)) == NULL) U->CPCount = 0;
- else {
- U->CPCount = StrHeadLen;
- U->CPChar = (*S)->StrChar;
- }
- }
-
- /*
- * CPRead
- *
- * Read up to N-1 characters from and advance a character pointer.
- * '\0' is returned as the last character of the string.
- *
- * Input
- * *U = character pointer
- * Buf = buffer into which to read characters
- * N-1 = number of characters to read
- *
- * Output
- * result = true if characters were read, 0 if end of string.
- * Buf = string of characters terminated by '\0'
- */
- boolean CPRead (U,Buf,N)
- register CharPtr *U;
- register char *Buf;
- register int N;
- {
- register char *S;
- register int K;
-
- if (!U->CPCount && (NULL==U->CPSeg || NULL==U->CPSeg->StrNext) ||
- !*(S = U->CPChar)) {
-
- *Buf = '\0';
- return 0;
-
- } else {
-
- --N;
- while (N > 0) {
- K = U->CPCount;
- if (K > N) K = N;
- N -= K;
- U->CPCount -= K;
- while (--K >= 0) *Buf++ = *S++;
- if (!U->CPCount) {
- if (NULL == (U->CPSeg = U->CPSeg->StrNext)) break;
- else {
- U->CPCount = StrTailLen;
- S = U->CPSeg->StrChar;
- }
- }
- }
- U->CPChar = S;
- *Buf = '\0';
- return 1;
- }
- }
-
-
- /*
- * CPAppend
- *
- * Append a character to the end of a string.
- *
- * A SysError may occur.
- */
- void CPAppend (U,C)
- register CharPtr *U;
- char C;
- {
- if (U->CPCount-- == 0)
- if (C == '\0') return;
- else {
- register StrPtr S = NewSCell ();
- if (SysError) return;
- else {
- U->CPChar = S->StrChar;
- if (*U->CPStr == NULL) {
- U->CPSeg = (*U->CPStr = S); /* Append head segment */
- U->CPCount = StrHeadLen-1;
- } else {
- U->CPSeg = (U->CPSeg->StrNext = S); /* Append tail segment */
- U->CPCount = StrTailLen-1;
- }
- }
- }
- *U->CPChar++ = C;
- }
-
-
- /*
- * LenStr
- *
- * Find the length of a FP string
- *
- * Input
- * S = IFP string
- *
- * Output
- * result = length of string in characters
- */
- FPint LenStr (S)
- register StrPtr S;
- {
- register int J = StrHeadLen;
- register FPint K = 0;
- register char *T;
-
- for (; S!=NULL; S = S->StrNext) {
- for (T = S->StrChar; --J >= 0 && *T; T++) K++;
- J = StrTailLen;
- }
- return K;
- }
-
-
- /*
- * DelSPtr
- *
- * Delete a string pointer: decrement reference count and remove string
- * if reference count is zero.
- */
- void DelSPtr (S)
- register StrPtr S;
- {
- register StrPtr T;
-
- semaphore_wait (SRefSemaphore);
- if (S != NULL && !-- S->SRef) {
- for (T=S; T->StrChar[0]='\0', T->StrNext!=NULL; T=T->StrNext) continue;
- T->StrNext = FreeString;
- FreeString = S;
- }
- semaphore_signal (SRefSemaphore);
- }
-
- /*
- * NewString
- *
- * Make a copy of a string. The old string retains its reference count.
- *
- * Input
- * S = pointer to string
- *
- * Output
- * result = pointer to new string
- *
- * A SysError may occur, in which case NULL is returned.
- */
- private StrPtr NewString (S)
- register StrPtr S;
- {
- extern char *strncpy ();
- register StrPtr R,T;
-
- if (S == NULL) return NULL;
- R = T = NewSCell (); /* R = root of copy */
- if (SysError) return NULL;
- (void) strncpy (T->StrChar,S->StrChar,StrHeadLen);
- while ((S=S->StrNext) != NULL) {
- T->StrNext = NewSCell ();
- T = T->StrNext;
- (void) strncpy (T->StrChar,S->StrChar,StrTailLen);
- if (SysError) {
- DelSPtr (R); /* flush copy */
- return NULL;
- }
- }
- return R;
- }
-
-
- /*
- * MakeString
- *
- * Make an IFP string from a C string.
- *
- * Input
- * S = pointer to character array terminated by '\0'
- *
- * Output
- * result = pointer to IFP (segmented) string
- *
- * A SysError may occur, in which case a NULL pointer is returned.
- */
- StrPtr MakeString (S)
- char *S;
- {
- extern char *strncpy ();
- int L=strlen(S);
-
- if (L <= 0) return NULL;
- else {
- StrPtr R,T;
- int N = StrHeadLen;
- R = T = NewSCell (); /* R = root of copy */
- if (SysError) return NULL;
- while (1) {
- (void) strncpy (T->StrChar,S,N);
- if ((L -= N) <= 0) return R;
- else {
- S += N;
- T->StrNext = NewSCell ();
- if (SysError) {
- DelSPtr (R); /* flush copy */
- return NULL;
- }
- T = T->StrNext;
- N = StrTailLen;
- }
- }
- }
- }
-
- /*
- * StrComp
- *
- * Compares two strings. Returns P-Q
- */
- int StrComp (P,Q)
- StrPtr P,Q;
- {
- register int Diff,Len;
- Len = StrHeadLen;
- while (1) {
- if (Q == NULL) return P!=NULL;
- else if (P == NULL) return -(Q!=NULL);
- else if (Diff = strncmp (P->StrChar,Q->StrChar,Len)) return Diff;
- else {
- Len = StrTailLen;
- P = P->StrNext;
- Q = Q->StrNext;
- }
- }
- }
-
- /*
- * Make a copy of a non-null string pointer, incrementing the reference count.
- *
- * A SysError may occur, in in which case a NULL pointer is returned.
- */
- StrPtr CopySPtr (S)
- StrPtr S;
- {
- semaphore_wait (SRefSemaphore);
- if (S != NULL && !++S->SRef) {
- S->SRef--;
- S = NewString (S);
- }
- semaphore_signal (SRefSemaphore);
- return S;
- }
-
- /*
- * InitString
- *
- * Initialize this module
- */
- void InitString ()
- {
- int C;
- StrPtr S;
-
- CharString = (StrPtr *) malloc (128 * sizeof (StrPtr));
- CharString [0] = NULL;
- for (C = 1; C<128; C++) {
- CharString [C] = S = NewSCell ();
- S->StrChar [0] = C;
- S->StrChar [1] = '\0';
- }
- }
-
- /************************** end of string.c **************************/
-
- SHAR_EOF
- if test -f 'interp/string.h'
- then
- echo shar: over-writing existing file "'interp/string.h'"
- fi
- cat << \SHAR_EOF > 'interp/string.h'
-
- /****** string.h ******************************************************/
- /** **/
- /** University of Illinois **/
- /** **/
- /** Department of Computer Science **/
- /** **/
- /** Tool: IFP Version: 0.5 **/
- /** **/
- /** Author: Arch D. Robison Date: May 1, 1985 **/
- /** **/
- /** Revised by: Arch D. Robison Date: Jan 20, 1987 **/
- /** **/
- /** Principal Investigators: Prof. R. H. Campbell **/
- /** Prof. W. J. Kubitz **/
- /** **/
- /** **/
- /**------------------------------------------------------------------**/
- /** (C) Copyright 1987 University of Illinois Board of Trustees **/
- /** All Rights Reserved. **/
- /**********************************************************************/
-
- /*
- * CharPtr
- *
- * Character pointer
- *
- * Character pointers are for an IFP string what file pointers are
- * for a UNIX file. Character pointers are used for both creating
- * (writing) and scanning (reading) IFP strings. The structure of
- * IFP strings (type String) is described in struct.h.
- */
- typedef struct {
- int CPCount; /* number of characters left in current segment */
- char *CPChar; /* pointer to current character */
- StrPtr *CPStr; /* pointer to root of string */
- StrPtr CPSeg; /* pointer to current segment of string */
- } CharPtr;
-
- extern StrPtr *CharString; /* from string.c */
- extern StrPtr MakeString ();
- extern void DelSPtr ();
- extern StrPtr CopySPtr ();
- extern void CPInit (), CPAppend ();
- extern boolean CPRead ();
- extern FPint LenStr ();
-
- /************************* end of string.h *************************/
-
- SHAR_EOF
- if test -f 'interp/struct.h'
- then
- echo shar: over-writing existing file "'interp/struct.h'"
- fi
- cat << \SHAR_EOF > 'interp/struct.h'
-
- /****** struct.h ******************************************************/
- /** **/
- /** University of Illinois **/
- /** **/
- /** Department of Computer Science **/
- /** **/
- /** Tool: IFP Version: 0.5 **/
- /** **/
- /** Author: Arch D. Robison Date: May 1, 1985 **/
- /** **/
- /** Revised by: Arch D. Robison Date: Aug 4, 1986 **/
- /** **/
- /** Principal Investigators: Prof. R. H. Campbell **/
- /** Prof. W. J. Kubitz **/
- /** **/
- /** **/
- /**------------------------------------------------------------------**/
- /** (C) Copyright 1987 University of Illinois Board of Trustees **/
- /** All Rights Reserved. **/
- /**********************************************************************/
-
- /*
- * There are some preprocessor variables which must be defined either
- * here or in the cc command. The following options are not available
- * in the public domain release:
- *
- * ARRAYS, COMPILE, UMAX, VECTOR, OUTBERKELEY
- *
- * Some of the code for these options are removed from the source by
- * unifdef(1), so the source may look strange in places. (E.g. degenerate
- * switch statements).
- *
- * The preprocessor variables are listed below.
- *
- * OPSYS (UNIX, MSDOS, CTSS) - specifies operating system
- * PCAT - for compiling on PC/ATs
- * SQUEEZE - put space at a premium
- * DEBUG - incorporate interpreter debugging spy points
- * DUMP - incoporate dump command for debugging (see debug.c)
- * REFCHECK - incorporate reference checking command (see apply.c)
- * COMPILE - incorporate IFP compiler (see C_comp.h)
- * ARRAYS - incorporate array representation of sequences
- * VECTOR - define APL-style vector operations (must define ARRAYS also)
- * UMAX - make parallel version for Encore Multimax
- *
- * There are also preprocessor variables which may be turned on or off
- * in the following files:
- *
- * ECACHE in cache.h - implement expression cache
- * STATS in stats.h - collect run time statistics
- * FETCH in node.h - implement "fetch" functional form
- * OUTBERKELEY in outberkely.h - implement routine to print functions in
- * Berkeley FP format.
- *
- * WARNING: Some of the compiling options may interfere with each other.
- * Some options have not been tested for many revisions, so
- * new bugs may creep out of the woodwork!
- */
-
- #define UMAX 0 /* Must not enable ARRAYS, ECACHE, or STATS if set */
- #define DUMP 0
- #define ARRAYS 0 /* Must also define VECTOR=1 if set */
- #define VECTOR 0
- #define DEBUG 0
- #define REFCHECK 0
-
- /*
- * Possible values for OPSYS preprocessor variable.
- */
- #define UNIX 10
- #define MSDOS 11
- #define CTSS 12
-
- #define OPSYS UNIX
-
- #if OPSYS==CTSS
- /*
- * PARAMBUG is defined to indicate that the C compiler can not
- * take the address (&) of parameter variables correctly.
- * When this bug is removed from the CRAY C compiler, this define
- * and dependent code should be removed.
- */
- #define PARAMBUG 1
- #endif
-
- #if OPSYS==MSDOS || OPSYS==CTSS
- #define MAXPATH 65 /* Maximum pathname length allowed (in characters) */
- #endif
-
- #if OPSYS==UNIX
- #define MAXPATH 256 /* Maximum pathname length allowed (in characters) */
- #endif
-
- #if OPSYS==CTSS
- #define index strchr
- #endif
-
- #ifdef PCAT
- #define index strchr
- #endif
-
- /********** Fundamental Data Structures and Constants **********/
-
-
- #define private static
- #define forward extern /* for forward definitions which are not external */
- typedef int boolean;
- typedef long FPint;
- typedef int FPboolean;
-
- typedef short ushort;
-
- /********************** MACHINE DEPENDENT CONSTANTS **********************/
-
- /* These two definitions assume two's complement arithmetic! */
- #define FPMaxInt (((FPint) 1 << 8 * sizeof(FPint) - 1) - 1)
- #define MaxInt ((( int) 1 << 8 * sizeof( int) - 1) - 1)
-
- #ifdef SQUEEZE
-
- /* Maximum floating point value representable by an FPfloat */
- typedef float FPfloat;
-
- #define MAXFLOAT 1e38
- #define LNMAXFLOAT 88.7
-
- #define CompTol (1e-6)
-
- #else
-
- typedef double FPfloat;
-
- /* Maximum floating point value representable by an FPfloat */
- #define MAXFLOAT 1.8e308
- #define LNMAXFLOAT 710.37 /* ln (MAXFLOAT) */
-
- #define CompTol (1e-8)
-
- #endif
-
- /* if abs(A),abs(B) are both < MAXFACTOR then A*B will fit in FPInt */
- #define MAXFACTOR 0xB504L
-
- /****************** end of machine dependent constants *********************/
-
- /********************************* Strings *********************************/
-
- /*
- * StrCell
- *
- * Each string is segmented into a linked list. The first record of the
- * linked list contains the reference count for the string.
- * The string is terminated by a segment with a null StrNext field or
- * a '\0', whichever comes first. The empty string is represented
- * by a null pointer. Segments have '\0' as their first character iff
- * they are in the free string list.
- */
-
- /*
- * StrHeadLen is the maximum number of characters which can be contained in
- * the first segment of a string list.
- */
- #if OPSYS==CTSS
- #define StrHeadLen 8 /* For 64-bit ushort and 64-bit pointer */
- #else
- #define StrHeadLen 10 /* For 16-bit ushort and 32-bit pointer */
- #endif
-
- #define StrTailLen (StrHeadLen + sizeof (ushort))
-
- typedef struct StrCell {
- struct StrCell *StrNext;
- union {
- char StrVar1 [StrTailLen];
- struct {
- char StrV1F1 [StrHeadLen];
- ushort StrV1F2;
- } StrVar2;
- } StrUni1;
- } StrCell;
-
- typedef StrCell *StrPtr;
-
- #define StrChar StrUni1.StrVar1
- #define SRef StrUni1.StrVar2.StrV1F2
-
- /****************************** Sequences ******************************/
-
- /*
- * Sequences are guaranteed not to have cycles by the definition of FP.
- * Note that function representation lists may have a cycle, but the cycle
- * will always contain a function name as a member. Cycle will be broken
- * when the function definition is deleted.
- */
-
- /* Object Tags */
- #define BOTTOM 0
- #define BOOLEAN 1
- #define INT 2
- #define FLOAT 3
- #define LIST 4
- #define STRING 5
- #define NODE 6
- #define CODE 7
- #define JOIN 8
-
- /* Bitmasks for PairTest */
- #define NUMERIC ((1<<FLOAT)|(1<<INT))
- #define ATOMIC (NUMERIC | (1<<BOOLEAN) | (1<<STRING))
-
-
- #define MAXTAG 7
- #define SEQUENCE (1<<LIST)
-
-
- /* Tag checking expressions dependent upon tag value assignments above */
- #define Scalar(Tag) ((Tag) < 4)
- #define Numeric(Tag) (((Tag)&~1)^2==0)
- #define NotNumPair(Tag1,Tag2) ((((Tag1)^2)|((Tag2)^2))&~1)
- #define IntPair(Tag1,Tag2) ((Tag1+Tag2) == 4)
-
- typedef struct CodeCell {
- int (*CodePtr) (); /* (*CodePtr) (InOut,CodeParam) */
- int CodeParam;
- } CodeCell;
-
- typedef union {
- FPfloat _Float;
- FPint _Int;
- FPboolean _Bool;
- struct ListCell *_List;
- StrPtr _String;
- struct NodeDesc *_Node;
- CodeCell _Code;
- } ObUnion;
-
- #define Float Data._Float
- #define Int Data._Int
- #define Bool Data._Bool
- #define List Data._List
- #define String Data._String
- #define Node Data._Node
- #define Code Data._Code
-
- /*
- * Note on ARRAYS structures. Cells with the ARRAY tag use the List field
- * to point to an array descriptor list. The first element of the list
- * uses the APtr field, subsequent elements use the ADim field.
- */
-
- /*
- * Object
- *
- * An Object is a union which stores an IFP object. The _LRef field is not
- * logically part of an * object, but rather part of a ListCell. We get much
- * better packing by including it in Object, since it fits in a 32-bit word
- * along with the Tag field.
- *
- * Likewise, for the UMAX version the _LRefLock field is physically part
- * of Object though it should be part of ListCell.
- *
- * Note that P->Val = Q->Val will transfer the reference count!
- */
- typedef struct {
- ObUnion Data;
- ushort _LRef;
- char Tag; /* BOTTOM,BOOLEAN,INT,FLOAT,LIST,STRING,NODE,CODE,ARRAY */
- } Object;
-
- /*
- * ListCell
- *
- * Sequences are represented as linked lists of objects. Each ListCell
- * also contains a reference count (hidden in the Object field). The
- * value stored in the reference count is offset by -1. The rationale is
- * that reference counts are always compared against one, and comparing
- * against zero is faster on some machines.
- */
- typedef struct ListCell {
- Object Val; /* Value of first element of sequence (CAR) */
- struct ListCell *Next; /* Pointer tail of sequence (CDR) */
- } ListCell;
-
- #define LRef Val._LRef
- #define LRefOne 0 /* value of LRef for reference count of 1 */
-
-
- /*
- * Most of the code uses subsets of the alphabet for certain types.
- * For example, P,Q, and R are usually ListPtr.
- */
- typedef ListCell *ListPtr; /* e.g. P,Q,R */
- typedef ListPtr *MetaPtr; /* e.g. A,B,C */
- typedef Object *ObjectPtr; /* e.g. X,Y,Z */
-
- #define NIL ((ListPtr) NULL) /* empty list */
-
- /******************************* Definitions ******************************/
-
- /*
- * DefDesc
- *
- * DefFlags = subset of {TRACE,RESOLVED}.
- * DefCode = code for definition - BOTTOM if not resident.
- */
- typedef struct DefDesc {
- char DefFlags;
- Object DefCode;
- } DefDesc;
-
- typedef DefDesc *DefPtr;
-
- #define TRACE 1 /* Print input and output. */
- #define RESOLVED 4 /* Mark bit used by reference checker */
-
- /*
- * All compiled FP functions have the following form:
- *
- * void F (InOut,CodeParam)
- * ObjectPtr InOut;
- * int CodeParam;
- * {...};
- *
- * F replaces *InOut with the result of applying F to *InOut.
- * CodeParam is optional.
- */
-
-
- /******************************* Modules *******************************/
-
- /*
- * Modules are stored as lists of nodes. Each node has a pointer to
- * its next sibling and its parent node.
- */
- typedef struct { /* Module node descriptor */
- struct NodeDesc *FirstChild;
- } ModDesc;
-
- /******************************** Imports ******************************/
-
- /*
- * Definition nodes are imported with IMPORT nodes. An import node in a
- * module points to a definition node elsewhere.
- */
- typedef struct {
- Object ImpDef; /* Can be path list or node */
- } ImpDesc;
-
- /******************************** Nodes ********************************/
-
- #define NEWNODE 0 /* Values for NodeType */
- #define MODULE 1
- #define DEF 2
- #define IMPORT 3
-
- /*
- * NodeDesc
- *
- * See the top of node.c for the description of how these are linked together
- * to form the function/module tree.
- *
- * NRef = reference count (references by objects)
- * NodeNext = pointer to next sibling (or parent).
- * NodeType = type of node (DEF, MODULE, IMPORT)
- * NodeName = print name of node.
- */
- typedef union {
- DefDesc NodeDef; /* if DEF */
- ModDesc NodeMod; /* if MODULE */
- ImpDesc NodeImp; /* if IMPORT */
- } NDunion;
-
- typedef struct NodeDesc {
- struct NodeDesc *NodeSib;
- struct NodeDesc *NodeParent;
- StrPtr NodeName;
- short NRef;
- char NodeType;
- NDunion NodeData;
- } NodeDesc;
-
- typedef struct NodeDesc *NodePtr;
-
- /*----------------- exception handling: see except.c -----------------*/
-
- /* values for SysError, 0 == no error */
-
- #define INTERNAL 1 /* Inexplicable internal error */
- #define NO_LIST_FREE 2 /* Ran out of list cell storage */
- #define NO_STR_FREE 3 /* " " " string " " */
- #define NO_NODE_FREE 4 /* " " " node " " */
-
- extern short SysError; /* An error occurred if SysError != 0 */
- extern short SysStop; /* Stop evaluation if != 0 */
-
- /*------------ debugging the interpreter: see debug.c ----------------*/
-
- /*
- * The interpreter may be compiled with internal spy points. These spy
- * points print internal information on stdout. To include the spy * points,
- * the interpreter must be compiled with #define DEBUG 1. To turn on a spy
- * point when running ifp, use the command line option '-d' followed by the
- * appropriate letters. The letters are defined by ``DebugOpt'' below.
- * For example,
- *
- * ifp -dar
- *
- * will turn on spy points related to memory allocation (a) and
- * reference counts (r).
- */
- #define DebugParse (1<<0) /* parser */
- #define DebugAlloc (1<<1) /* memory allocation */
- #define DebugFile (1<<2) /* file io */
- #define DebugRef (1<<3) /* reference counts */
- #define DebugInit (1<<4) /* initialization */
- #define DebugCache (1<<5) /* expression cache */
- #define DebugXDef (1<<6) /* extended definitions */
- #define DebugHyper (1<<7) /* hypercube */
- #define DebugUMax (1<<8) /* multimax */
- #define DebugSemaphore (1<<9) /* semaphores */
- #define DebugFreeList (1<<10) /* free list */
- #define DebugExpQueue (1<<11) /* expression queue */
-
- #define DebugOpt "pafricxhusle" /* option letters for above */
-
- #if DEBUG
- extern int Debug; /* Bit-set of enabled spy points */
- #else
- #define Debug 0 /* Turn spy points into dead code */
- #endif
-
- /*--------------------------------------------------------------------*/
-
- extern NodePtr CurWorkDir; /* Current working directory */
- extern NodePtr SysDef ();
-
- extern void DelLPtr (); /* Delete a list pointer */
- extern ListPtr CopyLPtr (); /* Copy a list pointer */
-
- extern void Rot3 (); /* list pointer rotation */
-
- extern long ListLength (); /* from list.c */
- extern void CopyObject ();
- extern ListPtr Repeat ();
- extern void NewList ();
- extern void RepTag ();
- extern boolean RepObject ();
- extern void RepLPtr ();
- extern void CopyTop ();
- extern void Copy2Top ();
- extern void RepBool ();
-
- extern void Apply (); /* from apply.c */
- extern NodePtr ApplyFun;
-
- extern void NodeExpand ();
-
- extern void ExecEdit (), ReadImport (); /* from file.c */
-
- extern void OutObject (), OutList (); /* from outob.c */
- extern void OutString (), OutNode ();
- extern void OutForm (), OutFun (); /* from outfun.c */
- extern void OutPretty ();
-
- extern void InitIn (), InBlanks (); /* from inob.c */
-
- extern void ReadDef (), DelImport ();
- extern void InImport ();
-
- extern int InError(); /* from error.c */
- extern void DefError (), IntError ();
- extern void FunError (), FormError ();
- extern char ArgNotSeq[], ArgObSeq[], ArgSeqOb[], ArgNull[], ArgBottom[];
-
- extern NodePtr PrimDef ();
- extern char *malloc();
-
- #define ArrayEnd(A) (A+(sizeof(A)/sizeof A[0]))
-
-
- /************************** end of struct.h **************************/
- SHAR_EOF
- if test -f 'interp/trace.c'
- then
- echo shar: over-writing existing file "'interp/trace.c'"
- fi
- cat << \SHAR_EOF > 'interp/trace.c'
-
- /****** trace.c *******************************************************/
- /** **/
- /** University of Illinois **/
- /** **/
- /** Department of Computer Science **/
- /** **/
- /** Tool: IFP Version: 0.5 **/
- /** **/
- /** Author: Arch D. Robison Date: May 1, 1985 **/
- /** **/
- /** Revised by: Arch D. Robison Date: Sept 9, 1986 **/
- /** **/
- /** Principal Investigators: Prof. R. H. Campbell **/
- /** Prof. W. J. Kubitz **/
- /** **/
- /** **/
- /**------------------------------------------------------------------**/
- /** (C) Copyright 1987 University of Illinois Board of Trustees **/
- /** All Rights Reserved. **/
- /**********************************************************************/
-
- #include <stdio.h>
- #include "struct.h"
- #include "umax.h"
-
- int TraceIndent = 0; /* Indentation level of trace */
- int TraceDepth = 2; /* Depth to which functions are printed */
-
- /*
- * PrintTrace
- *
- * Print a trace messages "ENTER>" or "EXIT> " with their arguments.
- * Each message is preceeded by an indentation pattern. Each '|' in
- * the pattern represents one level of indentation; each '.' in the
- * patttern represents DOTSIZE levels of indentation. The latter
- * abbreviation keeps us from going off the deep end.
- */
- #define DOTSIZE 20
-
- void PrintTrace (F,InOut,EnterExit)
- ObjectPtr F,InOut;
- char *EnterExit;
- {
- int K;
-
- /*
- * A SysStop >= 2 indicates multiple user interrupts, i.e. the user
- * does not want to see trace information.
- */
- if (SysStop < 2) {
- LineWait ();
- for (K = TraceIndent; K>=DOTSIZE; K-=DOTSIZE) printf (".");
- while (--K >= 0) printf (" |");
- printf (EnterExit);
- OutObject (InOut);
- printf (" : ");
- OutFun (F,TraceDepth);
- printf ("\n");
- LineSignal ();
- }
- }
-
- /******************************* end of trace.c ******************************/
-
- SHAR_EOF
- if test -f 'interp/umax.h'
- then
- echo shar: over-writing existing file "'interp/umax.h'"
- fi
- cat << \SHAR_EOF > 'interp/umax.h'
-
- /****** umax.h *******************************************************/
- /** **/
- /** University of Illinois **/
- /** **/
- /** Department of Computer Science **/
- /** **/
- /** Tool: IFP Version: 0.5 **/
- /** **/
- /** Author: Arch D. Robison Date: Nov 4, 1986 **/
- /** **/
- /** Revised by: Arch D. Robison Date: Jan 27, 1987 **/
- /** **/
- /** Principal Investigators: Prof. R. H. Campbell **/
- /** Prof. W. J. Kubitz **/
- /** **/
- /** **/
- /**------------------------------------------------------------------**/
- /** (C) Copyright 1987 University of Illinois Board of Trustees **/
- /** All Rights Reserved. **/
- /**********************************************************************/
-
- /*
- * Defining UMAX=1 in "struct.h" compiles the ifp interpreter for parallel
- * processing on the Multimax.
- */
-
- #define semaphore_wait(s)
- #define semaphore_signal(s)
- #define rsemaphore_enter(r)
- #define rsemaphore_exit(r)
- #define spin_lock(s)
- #define spin_unlock(s)
- #define LineWait()
- #define LineSignal()
- #define Terminate()
-
-
- /**************************** end of umax.h ****************************/
- SHAR_EOF
- if test -f 'interp/xdef.c'
- then
- echo shar: over-writing existing file "'interp/xdef.c'"
- fi
- cat << \SHAR_EOF > 'interp/xdef.c'
-
- /****** xdef.c ********************************************************/
- /** **/
- /** University of Illinois **/
- /** **/
- /** Department of Computer Science **/
- /** **/
- /** Tool: IFP Version: 0.5 **/
- /** **/
- /** Author: Arch D. Robison Date: Aug 4, 1986 **/
- /** **/
- /** Revised by: Arch D. Robison Date: Aug 4, 1986 **/
- /** **/
- /** Principal Investigators: Prof. R. H. Campbell **/
- /** Prof. W. J. Kubitz **/
- /** **/
- /** **/
- /**------------------------------------------------------------------**/
- /** (C) Copyright 1987 University of Illinois Board of Trustees **/
- /** All Rights Reserved. **/
- /**********************************************************************/
-
- /************************* Extended Definitions ************************/
-
- #include <stdio.h>
- #include "struct.h"
- #include "node.h"
- #include "inob.h"
-
- #if XDEF
-
- ListPtr Environment = NIL;
-
- /*
- * OutLHS
- *
- * Input
- * P = LHS to output
- */
- void OutLHS (InOut)
- ObjectPtr InOut;
- {
- switch (InOut->Tag) {
- case LIST: {
- register ListPtr P=InOut->List;
- printf ("[");
- if (P!=NIL)
- while (1) {
- if (Debug & DebugRef) printf ("{%d}",P->LRef + (1 - LRefOne));
- OutLHS (& P->Val);
- if ((P=P->Next) == NULL) break;
- else printf (",");
- }
- printf ("]");
- break;
- }
- default: OutObject (InOut);
- }
- }
-
- /*
- * Assign
- *
- * Assign functional variables.
- *
- * Input
- * X = object to be matched with LHS.
- * F = LHS
- */
- private boolean Assign (X,F)
- ObjectPtr X,F;
- {
- register ListPtr P,Q;
- extern StrPtr CopySPtr();
-
- switch (F->Tag) {
-
- case STRING:
- NewList (&Environment,2L);
- P = Environment;
- P->Val.Tag = STRING;
- P->Val.String = CopySPtr (F->String);
- CopyObject (&P->Next->Val,X);
- return 1;
-
- case LIST:
- if (X->Tag != LIST) return 0;
- else {
- for (Q=X->List,P=F->List; P!=NULL; Q=Q->Next,P=P->Next)
- if (Q==NULL || !Assign (&Q->Val,&P->Val)) return 0;
- return 1;
- }
-
- default:
- return 0;
- }
- }
-
- /*
- * FF_XDef
- *
- * Apply function F to each element of list InOut
- *
- * Input
- * InOut = list of elements to apply function
- * Funs = <lhs rhs function>
- *
- * Output
- * InOut = result
- */
- FF_XDef (InOut,Funs)
- ObjectPtr InOut;
- register ListPtr Funs;
- {
- ListPtr P;
- Object X;
- boolean InRange;
-
- if (3L != ListLength (Funs)) {
- FormError (InOut,"invalid xdef",NULL,Funs);
- return;
- }
- CopyObject (&X,InOut);
- Apply (&X,&Funs->Next->Val);
- P = Environment;
- InRange = Assign (&X,&Funs->Val);
- RepTag (&X,BOTTOM);
- if (InRange)
- Apply (InOut,&Funs->Next->Next->Val);
- else if (PrintErr (InOut)) {
- OutLHS (&Funs->Val);
- printf (": domain error\n");
- OutObject (InOut);
- printf ("\n");
- RepTag (InOut,BOTTOM);
- }
- RepLPtr (&Environment,P);
- }
-
- /*
- * InLHSC
- *
- * Input
- * F = input descriptor pointing to '['
- *
- * Output
- * result = true iff no error occurs
- * *X = sequence, or unchanged if error occurs.
- */
- private boolean InLHSC (F,X,Env)
- register InDesc *F;
- ObjectPtr X;
- ListPtr *Env;
- {
- register MetaPtr A;
- ListPtr R;
-
- *(A = &R) = NULL;
- F->InPtr++;
- InBlanks (F);
-
- while (']' != *F->InPtr) {
- if (!*F->InPtr) {
- DelLPtr (R);
- return InError (F,"unfinished construction");
- }
- NewList (A,1L);
- if (SysError || !InLHS (F,&(*A)->Val,Env)) {
- DelLPtr (R);
- return 0;
- }
- A = & (*A)->Next;
- if (*F->InPtr == ',') {
- F->InPtr++;
- InBlanks (F);
- }
- }
- F->InPtr++; /* Skip closing ']' */
- InBlanks (F);
- RepTag (X,LIST);
- X->List = R;
- return 1;
- }
-
- /*
- * InLHS
- *
- * Read a left-hand-side of a functional variable definition.
- * Return true iff no error occurred.
- *
- * Input
- * *F = input descriptor pointing to LHS
- *
- * Output
- * *F = input descriptor pointing to next token
- * *Lhs = left hand side
- * *Env = list of functional variables in LHS
- *
- * A SysError may occur, in which case X is unchanged.
- */
- boolean InLHS (F,LHS,Env)
- register InDesc *F;
- register ObjectPtr LHS;
- ListPtr *Env;
- {
- register ListPtr P;
-
- if (Debug & DebugParse) printf ("InLHS: %s",F->InPtr);
-
- if (*F->InPtr == '[') return InLHSC (F,LHS,Env);
- else {
- if (NULL == InString (F,LHS,NodeDelim,0))
- return InError (F,"variable name expected");
- for (P= *Env; P!=NULL; P=P->Next)
- if (ObEqual (&P->Val,LHS))
- return InError (F,"redefinition of variable (to left of caret)");
- NewList (Env,1L);
- CopyObject (&(*Env)->Val,LHS);
- return 1;
- }
- }
-
- #endif /* XDEF */
-
- /******************************* end of xdef.c *******************************/
-
- SHAR_EOF
- # End of shell archive
- exit 0
-
- --
-
- Rich $alz "Anger is an energy"
- Cronus Project, BBN Labs rsalz@pineapple.bbn.com
- Moderator, comp.sources.unix sources@uunet.uu.net
-